/**
 * 事件类，提供事件订阅、发布和移除功能
 */
export default class Event<Events extends Record<string, (...args: any[]) => void> = Record<string, () => void>> {
  /**
   * 存储事件回调的映射
   */
  protected events: Partial<{
    [K in keyof Events]: Array<Events[K]>;
  }> = {};

  /**
   * 订阅事件
   * @param event - 事件名称
   * @param callback - 事件触发时执行的回调函数
   */
  on<K extends keyof Events>(event: K, callback: Events[K]): void {
    if (!this.events[event]) {
      this.events[event] = [] as Array<Events[K]>;
    }
    (this.events[event] as Array<Events[K]>).push(callback);
  }

  /**
   * 取消订阅指定事件的回调函数
   *  - 想要正常off,在on时推荐使用箭头函数
   * @param event - 事件名称
   * @param callback - 要取消订阅的回调函数
   * @returns 是否成功取消订阅
   */
  off<K extends keyof Events>(event: K, callback: Events[K]): boolean {
    const fns = this.events[event] as Array<Events[K]> | undefined;

    if (!fns || fns.length === 0) {
      return false;
    }

    // 查找回调函数在列表中的位置
    const index = fns.findIndex((fn) => fn === callback);
    if (index === -1) {
      return false;
    }

    // 移除回调函数
    fns.splice(index, 1);

    // 如果移除后该事件没有回调了，可以考虑删除这个事件键
    if (fns.length === 0) {
      delete this.events[event];
    }

    return true;
  }

  /**
   * 发布事件
   * @param event - 事件名称
   * @param args - 传递给回调函数的参数
   */
  protected _emitEvent<K extends keyof Events>(event: K, ...args: Parameters<Events[K]>): boolean {
    const fns = this.events[event] as Array<Events[K]> | undefined;
    if (!fns || fns.length === 0) {
      return false;
    }
    fns.forEach((callback) => {
      callback(...args);
    });
    return true;
  }

  /**
   * 移除所有事件监听器
   */
  protected _removeEvents(): void {
    if (this.events && typeof this.events === 'object') {
      for (const event in this.events) {
        if (Object.prototype.hasOwnProperty.call(this.events, event)) {
          this.events[event as keyof Events] = [] as Array<Events[keyof Events]>;
        }
      }
    }
    this.events = {};
  }
}
